package ma.cdm.rapports;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Hashtable;

import javax.imageio.ImageIO;

import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.Reader;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.GlobalHistogramBinarizer;
import com.google.zxing.qrcode.QRCodeReader;
import com.google.zxing.qrcode.QRCodeWriter;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;

public final class QR {

  static final int PIXEL_SIZE =5;

  final BitMatrix bitMatrix;
  private Graphics2D g;
  private BufferedImage bufferedImage;
  int width, height, canvasWidth, canvasHeight, pixelSize;
  int inset = 4;
 static  final Hashtable hints = new Hashtable();

  @SuppressWarnings({ "unchecked", "rawtypes" }) 
  public QR(final String msg) throws Exception {
    final ErrorCorrectionLevel encLevel = ErrorCorrectionLevel.H; // L for lowest, H for highest.
    
    bitMatrix = new QRCodeWriter().encode(msg, BarcodeFormat.QR_CODE, 1, 1, hints);
    width =bitMatrix.getWidth() - inset * 2;
    height =bitMatrix.getHeight() - inset * 2;
    canvasWidth = width * PIXEL_SIZE;
    canvasHeight = height * PIXEL_SIZE;
    bufferedImage = new BufferedImage(150, 150, BufferedImage.TYPE_INT_ARGB);
    g = (Graphics2D) bufferedImage.getGraphics();
  }

  public void draw() {
    g.setColor(Color.WHITE);
    g.fillRect(5, 10, canvasWidth, canvasHeight);
    g.setColor(Color.BLACK);
    // Draw main image.
    for (int y = 0; y < height; y++) {
      for (int x = 0; x < width; x++) {
        final boolean on = bitMatrix.get(inset + x, inset + y);
        if (on) {
          g.fillRect(x * PIXEL_SIZE+5, y * PIXEL_SIZE+10, PIXEL_SIZE, PIXEL_SIZE);
        }
      }
    }
  }
  public  void mergeImageAndText(String text, int order)  {
			try{
			       
	      
			Font fnt=new Font("Times New Roman",1,12);
		    Color fntC = new Color(0, 0, 0);       
		    g.setColor(fntC);
		    g.setFont(fnt);
	        g.drawString(text,5, 500 -(order*20));
			}catch(Exception e)
			{
				e.printStackTrace();
			}
	    }

  public static String readImage(String outputFileName) 
  {
  	 
  	BufferedImage image;
  	try {
  		image = ImageIO.read(new File(outputFileName));
  		
  	} catch (Exception iae) {
  		iae.printStackTrace();
  		System.out.println("Resource not found: " + outputFileName);
  		return null; 		
  	}
  	
  	Reader reader = new MultiFormatReader();
  	LuminanceSource source = new BufferedImageLuminanceSource(image);
  	BinaryBitmap bitmap = new BinaryBitmap(new GlobalHistogramBinarizer(source));
  	
  	Collection<Result> results = new ArrayList<Result>(1);
  	
  	try {
  		final ErrorCorrectionLevel encLevel = ErrorCorrectionLevel.H; // L for lowest, H for highest.
  	    final Hashtable hints = new Hashtable();
  	  hints.put(EncodeHintType.ERROR_CORRECTION, encLevel);
  		  Result theResult = new QRCodeReader().decode(bitmap,hints);
  		  if (theResult != null) { 		 
  		    return theResult.toString();
  		  }
  		} catch (ReaderException re) {
  		  //re.printStackTrace();
  		  return null;
  		}
  	return null;
  }
public BufferedImage getBufferedImage() {
	return bufferedImage;
}

public void setBufferedImage(BufferedImage bufferedImage) {
	this.bufferedImage = bufferedImage;
}

void write(final File fileOutPut) throws IOException {	
    ImageIO.write(bufferedImage, "PNG", fileOutPut);
    g.dispose();
  }
}
